<html>
<head>
    <title>living</title>
    <!-- 必须放在<head>的最前面 -->
    <meta charset="UTF-8">
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <link href="../css/index.css" type="text/css" rel="stylesheet"></link>
    <link rel="stylesheet" href="//apps.bdimg.com/libs/jqueryui/1.10.4/css/jquery-ui.min.css">
    <link rel="stylesheet" href="https://www.runoob.com/try/demo_source/jqueryui/style.css">
</head>
<style>
html, body {
  height: 100%;
  margin: 0;
}
.con {
  display: flex; /* 启用Flexbox布局 */
  height: 100%;
}

.left {
  flex: 2; /* 左边div占据剩余空间的1/3 */
  padding: 10px;
  border-right: 1px solid #000000;
}

.right {
  flex: 1; /* 右边div占据剩余空间的2/3 */
  background-color: lightgrey;
  padding: 10px;

  max-height: 100vh; /* 设置最大高度为视口的100% */
  overflow-y: auto; /* 启用垂直滚动条 */
  overflow-x: hidden; /* 隐藏水平滚动条 */


}


.content-panel {
  display: flex;
  align-items: center; /* 垂直居中 */
  justify-content: space-between; /* 左右内容对齐 */
  width: 100%; /* 根据需要调整宽度 */
  padding-top: 10px; /* 根据需要调整内边距 */
}

.content {
  /* 内容样式 */
  margin-left: 5px;;
}

.button {
  /* 按钮样式 */
  margin-right: 5px;
}
.demo-tabs > .el-tabs__content {
  padding: 32px;
  color: #6b778c;
  font-size: 32px;
  font-weight: 600;
}

.canvas{
    width: 800px;
    height: 500px;
    border: 1px solid #000 ;
    border-radius: 20px;
    box-shadow: 5px 5px 5px #000;
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -400px;
    margin-top: -300px;
}
.btn_box{
    text-align: center;
    margin: auto;
    position: absolute;
    height: 100px;
    left: 50%;
    top: 50%;
    margin-left: -400px;
    margin-top: 250px;

}
.btn_box button{
    border: none;
    width: 80px;
    height: 40px;
    border: 1px solid gray;
    border-radius: 20px;
    margin-left: 25px;
}

</style>
<body>

    <div class="con">
        <div class="left">

          <div id="tabs" style="flex: auto;height:100%;">
            <ul>
              <li><a href="#tabs-1">draw</a></li>
              <li><a href="#tabs-2">file</a></li>
            </ul>
            <div id="tabs-1" style="width: 100%;margin-top: 20px;">


                <!-- 画室 -->
                <div class="canvas">
                    <canvas width="800px" height="500px"></canvas>
                </div>
                <div class="btn_box">
                    <button class="brush" >brush</button>
                    <button class="clear" >clear</button>
                    <button class="erase" >brush</button>
                    <button class="save">save</button>
                    <span>color:</span><input type="color" class="color" />
                    <span>bold:</span><input type="range" class="range" min="1" max="20" value="1" />
                </div>

            </div>
            <div id="tabs-2" style="width: 100%;">

                <div style="display:flex;" id="filelist">

                </div>
                <iframe src="" width="100%" style="border: none;height:600px;margin-top:10px;padding-right: 20px;box-sizing: border-box;" id="file"> </iframe>

            </div>

          </div>

        </div>
        <div class="right">
          <div class="content-panel" style="padding-bottom:5px;">
              <div class="content">
                  <h4>Living</h4>
              </div>
              <div class="button">
                <button class="taste-button ready-button" onclick="stoplive()">stop live</button>
                <button class="taste-button ready-button" id="taste_button">start transcript</button>
                <button class="taste-button start-button" id="stopbutton">stop transcript</button>
                <button class="taste-button ready-button" onclick="sharescreen()">sharescreen</button>
                  <!-- <el-button type="primary" :icon="Share" circle @click="sharescreen()"/> -->
              </div>
          </div>

          <div class="content-panel" style="padding-top:5px;">

            <div class="output-box" id="result_output"></div>

          </div>

        </div>
      </div>
<script src="../js/utils.js" charset="utf-8"></script>
<script src="../js/full.js"></script>
<!-- 百度语音翻译 -->
<script src="../js/hmac-sha256.js"></script>
<script src="../js/HmacSHA1.js"></script>
<script src="../js/md5.js"></script>
<script src="../js/enc-base64-min.js"></script>
<script src="../js/jquery.js"></script>
<script src="../js/transindex.js"></script>
<!-- <script src="//apps.bdimg.com/libs/jquery/1.10.2/jquery.min.js"></script> -->
<script src="//apps.bdimg.com/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<script src="../js/base64.js"></script>

<!-- 画板操作相关事件 -->
<script src="../js/Canvas.js" charset="utf-8"></script>

<script type="text/javascript">

//const baseurl = 'http://localhost:8080';
//const proviewurl = 'http://192.168.0.102:8012';
//const socketurl = 'ws://localhost:8080/websocket';

const baseurl = 'https://notewave.net/api';
const chatBaseurl = 'https://notewave.net';
const proviewurl = 'http://16.162.220.253:8012';
const socketurl = 'wss://notewave.net:443/websocket';
const tname = localStorage.getItem('username');
const payload = JSON.parse(tname);
const username = payload.username;

const url = new URL(window.location.href);
// 获取查询参数
const queryParams = new URLSearchParams(url.search);
const lessionid = queryParams.get('lessionid');
const courseid = queryParams.get('courseid');

const TYPE_COMMAND_ROOM_ENTER = "enterRoom";
const TYPE_COMMAND_ROOM_LIST = "roomList";
const TYPE_COMMAND_DIALOGUE = "dialogue";
const TYPE_COMMAND_READY = "ready";
const TYPE_COMMAND_OFFER = "offer";
const TYPE_COMMAND_ANSWER = "answer";
const TYPE_COMMAND_CANDIDATE = "candidate";


let iceServers={
    "iceServers":[
        {"url":"stun:stun.services.mozilla.com"},
        {"url":"stun:stun.l.google.com:19302"}
    ]
};

const offerOptions = {
    iceRestart: true,
    offerToReceiveAudio: false, //true,由于没有麦克风，所有如果请求音频，会报错，不过不会影响视频流播放
    offerToReceiveVideo: true
};

let websocket;
let localMediaStream;
let videoStream;
let rtcPeerConnection;
let peerConnections = {};

$(function() {

    $( "#tabs" ).tabs();

    loaddata();
});

function loaddata()
{
    const url = baseurl+'/user/getMyLessionFileList';
    const params = {lessionid:lessionid};
    get(url,params).then((res) => {
        if (res.code == 200)
        {
            //alert(res.data[0].filepath);
            //<el-button @click="reseturl(item.filepath)">{{item.name}}</el-button>
            //filelist 动态插入
            var filelist = res.data;
            var tempElement = '';
            for (var i = 0; i < filelist.length; i++) {
                //alert(filelist[i].filepath); // 输出每个列表项的文本内容
                tempElement += "<button onclick='reseturl(\""+filelist[i].filepath+"\")'>"+filelist[i].name+"</button>&nbsp";
                //"<button onclick='reseturl(\'"+filelist[i].filepath+"\')'>"+filelist[i].name+"</button>&nbsp;"
            }
            $('#filelist').append(tempElement);
            // 获取iframe元素
            var iframe = $("iframe");
            // 修改src属性
            var url = baseurl +"/"+res.data[0].filepath
            //用4.0版本
            //iframe.attr("src", proviewurl +"/onlinePreview?url=" + encodeURIComponent(Base64.encode(url)));
            if (url.toLowerCase().endsWith('.pdf'))
            {
                iframe.attr("src", url);
            }
            else
            {
                //用2.2版本
                iframe.attr("src", proviewurl +"/onlinePreview?url=" + encodeURIComponent(url));
            }
        //lessionfiledata.list = res.data;
        //var baseurl = import.meta.env['VITE_APP_BASE_API']
       // var proviewurl = import.meta.env['VITE_PROVIEW']
       // var url = baseurl +"/"+lessionfiledata.list[0].filepath
        //lessiondata.urlSrc = proviewurl +"/onlinePreview?url=" + encodeURIComponent(Base64.encode(url))
        }
    })
}
function reseturl(filepath)
{
    var iframe = $("iframe");
    // 修改src属性
    var url = baseurl +"/"+filepath
    if (url.toLowerCase().endsWith('.pdf'))
    {
        iframe.attr("src", url);
    }
    else
    {
        //用2.2版本
        iframe.attr("src", proviewurl +"/onlinePreview?url=" + encodeURIComponent(url));
    }
}
const handleMessage = (event) => {
    let message = JSON.parse(event.data);
    switch (message.command) {
        case TYPE_COMMAND_ROOM_ENTER://进入房间，然后打开本地共享桌面流媒体
            // 进入房间后打开本地共享
            openLocalMedia()
                .then(() => {})
                .catch((e) => {
                    alert(e);
                });
            break;
        case TYPE_COMMAND_ROOM_LIST:
            break;
        case TYPE_COMMAND_DIALOGUE:
            break;
        case TYPE_COMMAND_READY:
            // 为每个新观众创建独立的PeerConnection
            if (!peerConnections[message.username]) {
                let pc = new RTCPeerConnection(iceServers);
                peerConnections[message.username] = pc;

                pc.onicecandidate = (event) => onIceCandidate(event, message.username);
                pc.ontrack = onTrack;

                // 添加轨道
                for (const track of localMediaStream.getTracks()) {
                    pc.addTrack(track, localMediaStream);
                }

                pc.createOffer(offerOptions)
                    .then(offer => setLocalAndOffer(offer, pc, message.username))
                    .catch(console.error);
            }
            break;
        case TYPE_COMMAND_OFFER:
            // 处理观众端的Offer（主播作为接收方）
            if (!peerConnections[message.username]) {
                let pc = new RTCPeerConnection(iceServers);
                peerConnections[message.username] = pc;

                pc.onicecandidate = (event) => onIceCandidate(event, message.username);
                pc.ontrack = onTrack;

                // 添加本地轨道
                if (localMediaStream) {
                    for (const track of localMediaStream.getTracks()) {
                        pc.addTrack(track, localMediaStream);
                    }
                }
            }

            const pc = peerConnections[message.username];
            let sdpMessage1 = message.message;
            sdpMessage1 = sdpMessage1.replace(/[\r]/g, "\\r").replace(/[\n]/g, "\\n");
            let sdp1 = JSON.parse(sdpMessage1).sdp;

            pc.setRemoteDescription(new RTCSessionDescription(sdp1))
                .then(() => {
                    return pc.createAnswer(offerOptions);
                })
                .then(answer => {
                    return setLocalAndAnswer(answer, pc, message.username);
                })
                .catch(error => {
                    console.error('Offer handling error:', error);
                });

            break;
        case TYPE_COMMAND_ANSWER:
            //原因：后端接口返回的数据换行采用了\r\n方式，使得json文本无法解析带换行符的内容
            //解决方法：将Json字符串中所有的\r\n转成\\r\\n
            //let sdpMessage = message.message;
            //sdpMessage.replace(/[\r]/g, "\\r").replace(/[\n]/g, "\\n");
            // 处理观众端的Answer
            if (peerConnections[message.username]) {
                let sdpMessage = message.message;
                sdpMessage = sdpMessage.replace(/[\r]/g, "\\r").replace(/[\n]/g, "\\n");
                let sdp = JSON.parse(sdpMessage).sdp;

                peerConnections[message.username].setRemoteDescription(
                    new RTCSessionDescription(sdp)
                ).catch(error => {
                    console.error('Set remote description error:', error);
                });
            }

            break;
        case TYPE_COMMAND_CANDIDATE:
            // 处理观众端的ICE Candidate
            if (peerConnections[message.username]) {
                let candidateMessage = message.message;
                let candidate = JSON.parse(candidateMessage).candidate;
                let rtcIceCandidate = new RTCIceCandidate({
                    sdpMid: candidate.sdpMid,
                    sdpMLineIndex: candidate.sdpMLineIndex,
                    candidate: candidate.candidate
                });

                peerConnections[message.username].addIceCandidate(rtcIceCandidate)
                    .catch(error => {
                        console.error('Add ICE candidate error:', error);
                    });
            }
            break;
    }
};


const openLocalMedia = async () => {
    videoStream = await navigator.mediaDevices.getDisplayMedia({
        video: {MediaSource: "screen"},audio:false
    });
    const audioStream = await navigator.mediaDevices.getUserMedia({
        video:false,
        audio: {
            sampleSize: 100,
            frameRate: { max: 30 },
            noiseSuppression: true,
            echoCancellation: true,
            channelCount: 2
        }
    });
    videoStream.getVideoTracks()[0].onended = ()=>{
        console.log("onended----------------------------->")
      	leave();
    };
    var audioTrack = audioStream.getAudioTracks()[0];
    videoStream.addTrack(audioTrack);

    localMediaStream = videoStream;
    //测试添加到localVideo查看分享效果
    //let localVideo = document.getElementById("localVideo");
    //localVideo.srcObject = localMediaStream;
    //localVideo.play();

}

function leave()
{
    console.log("leave ----------------------------->");
    // 关闭所有PeerConnection
    Object.keys(peerConnections).forEach(username => {
        peerConnections[username].close();
        delete peerConnections[username];
    });

    // 关闭本地媒体流
    if (localMediaStream) {
        localMediaStream.getTracks().forEach(track => track.stop());
    }

    // 关闭WebSocket
    if (websocket) {
        websocket.close();
    }

}
function initwebsocket()
{

}
async function stoplive()
{
    const url = baseurl+'/user/updateCourseLive';
    const params = {"id":courseid,"type":0};
    post(url,params).then((res) => {
        if (res.code == 200)
        {
            alert("stop success");
        }
    })
    var content = '';
    //lessionfile列表
    var lessionfiledata = [];
    const getMyLessionTransfileListUrl = baseurl+'/user/getMyLessionTransfileList';
    const myLessionTransfileParams = {"lessionid":lessionid};
    get(getMyLessionTransfileListUrl,myLessionTransfileParams).then((res) => {
    if (res.code == 200)
    {
      lessionfiledata = res.data;
      for(let item of lessionfiledata){
        for(let scriptitem of item.list){
          content += scriptitem.encontent + '\n'
        }
      }
      sendMessage(content+"请对以上英文段落分别用英文和繁体中文进行总结，要求语句简约且通顺。英文总结和繁体中文总结间要换行",lessionid)
    }
  })
}


async function sendMessage(encontent,lessionid){
  let eventSource = null;
  var messages = [];
  if (!encontent) return
  // 只有当eventSource不存在时才创建新的EventSource连接
  if (!eventSource) {
    // messages.push({ text: encontent, sender: 'user' });
    messages.push({ text: "", sender: 'ai' });
    // 创建新的EventSource连接
    eventSource = new EventSource(chatBaseurl+'/chat?content=' + encontent);
    //设置消息接收的回调函数
    eventSource.onmessage = (event) => {
      const data = JSON.parse(event.data);
      messages[messages.length - 1].text += data.result;
    };
    // 可选：监听错误事件，以便在出现问题时能够重新连接或处理错误
    eventSource.onerror = (event) => {
      console.error("EventSource failed:", event);
     // 获取原始数组
    // const rawArray = toRaw(messages);
    const regex = /英文总结：\s*(.+?)\s*繁体中文总结：\s*(.+)/;
    const matches = messages[0].text.match(regex);
    const url = baseurl+"/summary/save"
    const params = {"lessionid":lessionid,"ywContent":matches[1],"zwContent":matches[2]};

     post(url,params).then((res) => {
        if (res.code == 200)
        {
            console.log("总结生成成功");
        }else{
            console.log("总结生成失败");
        }
    })


      eventSource.close(); // 关闭出错的连接
      eventSource = null; // 重置eventSource变量，允许重建连接
    };
  }
}

//发起共享屏幕的指令
function sharescreen()
{
    //连接到课程lession的直播websocket
    if (!websocket) {
        websocket = new WebSocket(socketurl);
    }
    websocket.onopen = () => {
        //连接到课程lession的直播websocket
        websocket.send(JSON.stringify({command:TYPE_COMMAND_ROOM_ENTER,username:username,roomId : lessionid}));

        // 添加心跳机制
        setInterval(() => {
            if (websocket.readyState === WebSocket.OPEN) {
                console.log("heartbeat-------------------")
                websocket.send(JSON.stringify({command: "heartbeat"}));
            }
        }, 30000); // 每30秒发送一次心跳

    };
    websocket.onclose = () => {

        videoStream.getTracks().forEach(track => {
            track.stop();
        });
        websocket = '';
        videoStream = '';
        localMediaStream = '';
    };
    websocket.onerror = () => {
    };
    websocket.onmessage = handleMessage;
}

const setLocalAndOffer = (sessionDescription, pc, targetUser) => {
    pc.setLocalDescription(sessionDescription)
        .then(() => {
            websocket.send(JSON.stringify({
                command: TYPE_COMMAND_OFFER,
                username: username,
                target: targetUser,
                roomId: lessionid,
                message: {
                    sdp: sessionDescription,
                }
            }));
        })
        .catch(error => {
            console.error('Set local offer error:', error);
        });
};
const setLocalAndAnswer = (sessionDescription, pc, targetUser) => {
    pc.setLocalDescription(sessionDescription)
        .then(() => {
            websocket.send(JSON.stringify({
                command: TYPE_COMMAND_ANSWER,
                username: username,
                target: targetUser,
                roomId: lessionid,
                message: {
                    sdp: sessionDescription,
                }
            }));
        })
        .catch(error => {
            console.error('Set local answer error:', error);
        });
};
const onTrack = (event) =>{
    // let remoteMediaStream = event.streams[0];
    // let remoteVideo = document.getElementById("remoteVideo");
    // remoteVideo.srcObject = remoteMediaStream;
    // remoteVideo.play();

};

// const onIceCandidate = (event) =>{
//     if (event.candidate) {
//         //log("sending ice candidate");
//         try {
//         websocket.send(JSON.stringify({
//             command: TYPE_COMMAND_CANDIDATE,
//             username:username,
//             roomId: lessionid,
//             message: {
//                 candidate:{
//                     sdpMid: event.candidate.sdpMid,
//                     sdpMLineIndex: event.candidate.sdpMLineIndex,
//                     candidate: event.candidate.candidate
//                 }
//             }
//         }));
//         } catch (e) {}
//     }
// };

const onIceCandidate = (event, targetUser) => {
    if (event.candidate) {
        websocket.send(JSON.stringify({
            command: TYPE_COMMAND_CANDIDATE,
            username: username,
            target: targetUser,
            roomId: lessionid,
            message: {
                candidate: {
                    sdpMid: event.candidate.sdpMid,
                    sdpMLineIndex: event.candidate.sdpMLineIndex,
                    candidate: event.candidate.candidate
                }
            }
        }));
    }
};
</script>
</body>
</html>
